home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0" encoding="utf-8" ?>
- <!DOCTYPE stack PUBLIC "-//Apple, Inc.//DTD stack V 2.0//EN" "" >
- <stack>
- <name>in.3</name>
- <id>-1</id>
- <cardCount>3</cardCount>
- <cardID>2959</cardID>
- <listID>4019</listID>
- <cantModify><false /></cantModify>
- <cantDelete><false /></cantDelete>
- <cantAbort><false /></cantAbort>
- <cardSize>
- <width>256</width>
- <height>288</height>
- </cardSize>
- <script>∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- THE DELIMITER FIXER
- ©1991 Geoff Duncan, Red Split Ends Inc.
- This stack is free, although the author maintains copyright. You may
- not sell this stack or charge for its distribution without the express permission
- of the author AND the author(s) of materials contained herein.
-
- XFCNs used in this stack:
- HierPopUpMenus, © Jon Pugh jpugh@apple.com
- XCMDs used in this stack:
- HCBalloon, © Len Saaf saaf@joker.optics.rochester.edu
- Used within limits specified by the authors.
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- on openstack
- if the version < 2.1 then
- answer the short name of this stack && "requires HyperCard 2.1 or higher." && ¬
- "Many features of this stack will not work properly with an earlier version of HyperCard."¬
- & return & "See the Stack OverView for more information."
- end if
- put "<<none>>" into bg fld "Import"
- put "<<none>>" into bg fld "Export"
- -- put empty into bg fld "Specified Header"
- dfremovemask
- hide bg btn id 32 --ok
- hide bg btn id 46 --save
- hide bg fld "Specified Header"
- DFSetUpMenu On
- pass openstack --for others
- end openstack
-
- on closestack
- global DFImportFile, DFExportFile,FieldDelimiter,RecordDelimiter
- put empty into DFImportFile
- put empty into DFExportFile
- put empty into FieldDelimiter
- put empty into RecordDelimiter
- if the freesize of this stack > .1 * the size of this stack then
- put the freesize of this stack div 1024 & "K free in stack" && the short name¬
- of this stack & ". Compacting..."
- domenu "Compact Stack"
- hide msg
- end if
- DFSetUpMenu Off
- pass closestack --ferothers
- end closestack
-
- on suspendStack
- DFSetUpMenu Off
- pass suspendstack --for others, if any
- end suspendstack
-
- on resumeStack
- DFSetUpMenu On
- send "opencard" to this card
- pass resumeStack --for others, if any
- end resumeStack
-
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- MAIN CARD HANDLERS
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
-
- --asks for and obtains paths for import and export files
- on DFgetAFile which
- global DFImportFile, DFExportFile
- if which is "Import" then
- answer file "Please name an" && which && "file:" of type TEXT
- else
- ask file "Please name an" && which && "file:"
- end if
- if (it is not empty) or (the result is not "Cancel") then
- put FileFromPath(it) into bg fld which
- if which is "import" then put it into DFImportFile
- else put it into DFExportFile
- else put "<<none>>" into bg fld which
- end DFgetAFile
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- on GODelimiterFixer
- --
- GetUserSettings -- gets user settings
- if the result is empty then exit GODelimiterFixer
- --
- GetProperHeader
- put the result into DFHeader
- if DFHeader is empty then exit GODelimiterFixer
- ParseTheHeader DFHeader
- put the result into DFHeader
- if DFHeader is empty then exit GODelimiterFixer
- --
- if the hilite of bg btn "Variable to fixed" then VarToFixed DFHeader
- else FixedToVar DFHeader
- --
- play finis f c g cw
- end GODelimiterFixer
-
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- on GetUserSettings
- global DFImportFile, DFExportFile,FieldDelimiter, RecordDelimiter
- if (bg fld "Import" is empty) or (bg fld "import" is "<<none>>") then
- beep
- answer "No import file specified." with "OK"
- return empty -- puts empty into "the result" for later processing
- end if
- if (bg fld "Export" is empty) or (bg fld "Export" is "<<none>>") then
- beep
- answer "No export file specified." with "OK"
- return empty -- puts empty into "the result" for later processing
- end if
- if DFImportFile is DFExportFile then
- beep
- answer "Import and Export files may not be identical." with "Oh hell."
- put "<<none>>" into bg fld Import
- put "<<none>>" into bg fld Export
- return empty
- end if
- --now obtains user settings and puts them into the appropriate global variables
- -- used in the routines. Also puts the appropriate character values in where needed.
- put the short name of bg btn id 5 into FieldDelimiter
- put the short name of bg btn id 15 into RecordDelimiter
- if fieldDelimiter is RecordDelimiter then
- beep
- answer "Field and Record delimiters may not be identical." with "Oh hell."
- return empty
- end if
- --those are the "popup" buttons
- if (FieldDelimiter is "Colon")¬
- or (FieldDelimiter is "Tab")¬
- or (FieldDelimiter is "Comma")¬
- or (FieldDelimiter is "Space") then
- put value(FieldDelimiter) into FieldDelimiter
- else
- if (FieldDelimiter is "SemiColon") then put ";" into FieldDelimiter
- end if
- if (RecordDelimiter is "Return")¬
- or (RecordDelimiter is "Tab")¬
- or (RecordDelimiter is "Space") then
- put value(RecordDelimiter) into RecordDelimiter
- end if
- --
- return true
- end GetUserSettings
-
- on GetProperHeader
- --returns the appropriate header for operation... returns EMPTY if none
- global RecordDelimiter, DFImportFile
- put empty into WhichHeader
- open file DFImportFile
- read from file DFImportFile until RecordDelimiter --gets header information if present
- put it into FirstLine
- close file DFImportFile
- put bg fld "Specified Header" into SpecHeader
- --here's the testing section
- if isValidHeader(FirstLine) and isValidHeader(SpecHeader) then
- --BOTH ARE VALID
- answer "The file" && quote & FileFromPath(DFImportFile) & quote &&¬
- "apparently contains valid header information." && ¬
- "Do you wish to use this information or the header you supplied?" ¬
- with "FileΓÇÖs" or "Mine" or "Cancel"
- if it is "Cancel" then return empty
- put it into whichHeader
- end if
- if isValidHeader(SpecHeader) and ¬
- ((whichHeader is empty) or (whichHeader is "Mine")) then return SpecHeader
- --SPECHEADER VALID
- if isValidHeader(firstLine) and ¬
- ((WhichHeader is empty) or (WhichHeader is "FileΓÇÖs")) then return FirstLine
- --FIRSTLINE VALID
- if not(isValidHeader(firstLine)) and not(isValidHeader(SpecHeader)) then
- --BOTH ARE INVALID
- answer "Neither the file" && quote & FileFromPath(DFImportFile) & quote &&¬
- "nor this stack contain a valid Header. Please see this stack’s documentation" &&¬
- "for information about creating a Header." with "OK"
- return empty
- end if
- end GetProperHeader
-
- on ParseTheHeader Header
- --this leaves us with a return-separated list
- global fieldDelimiter
- if not(isValidHeader(header)) then return empty
- if header contains fieldDelimiter then put FieldDelimiter into Delim
- else put comma into Delim
- if not(header contains Delim) then
- answer "The specfied Header is not valid. Please see this stack’s documentation" &&¬
- "for information on creating a valid Header." with "OK"
- return empty
- end if
- put StripReturnsAndSpaces(header) into header
- delete char 1 to 2 of header --removes <<
- put the number of chars in header into lastChar
- delete char lastchar -1 to lastchar of header --removes >>
- --this removes all FIELDDELIMITERS so we can parse out column notations
- repeat with i = 1 to the number of chars in header
- if char i of header is Delim then put return into char i of header
- end repeat
- return Header
- end ParseTheHeader
-
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
-
- on VarToFixed Columns
- global DFImportFile, DFExportFile, FieldDelimiter, RecordDelimiter, DFDATA
- if columns is "PreWarm" then exit VarToFixed
- disallowinterruption
- DFSetUpMask
- open file DFImportFile
- open file DFExportFile
- if not(the hilite of bg btn "Low Memory Mode") then LoadAllData DFImportFile --Γêå
- put 0 into processedRecords
- set the itemdelimiter to FieldDelimiter
- repeat -- until eof
- if UserInterrupt() then exit repeat
- -- read from file DFImportFile until RecordDelimiter -- one "line"
- get theNextRecord()
- if it is empty then exit repeat
- put it into Field
- -- delete the last char of Field -- the record delimiter
- put empty into FixedFields
- repeat with i = 1 to the number of lines in Columns
- set cursor to busy
- ConvertToFixedField item i of Field, line i of columns
- put the result after FixedFields
- end repeat
- write FixedFields & return to file DFExportFile
- put ProcessedRecords + 1 into ProcessedRecords
- DFMaskMessage "Records Processed:" && ProcessedRecords & return & ¬
- "Hold down ∩ú┐-option-mouse to interrupt."
- end repeat
- CleanUpStuff
- end VarToFixed
-
- on ConvertToFixedField field, columns
- put the number of chars in field into FieldChars
- if FieldChars > columns then
- delete char columns + 1 to (fieldchars) of field
- return field
- else
- repeat columns - fieldchars times
- put space after field
- end repeat
- return field
- end if
- end ConvertToFixedField
-
- on FixedToVar Columns
- --converts fixed-field format to variable-length
- global DFImportFile, DFExportFile, FieldDelimiter, RecordDelimiter, DFDATA
- if columns is "PreWarm" then exit FixedToVar
- disallowinterruption
- DFSetUpMask
- open file DFImportFile
- open file DFExportFile
- if not(the hilite of bg btn "Low Memory Mode") then LoadAllData DFImportFile --Γêå
- put 0 into processedRecords
- repeat
- if UserInterrupt() then exit repeat
- -- read from file DFImportFile until return --gets one line
- get theNextRecord()
- if it is empty then exit repeat
- put it into Record
- put 1 into FirstChar
- repeat with i = 1 to the number of lines in columns
- set the cursor to busy
- put stripReturnsAndSpaces(char FirstChar to (firstChar +line i of Columns -1)¬
- of Record) after VarRecord
- put varRecord & FieldDelimiter into VarRecord
- put firstChar + line i of Columns into firstChar
- end repeat
- put recordDelimiter into the last char of VarRecord
- write VarRecord to file DFExportFile
- put empty into VarRecord
- put ProcessedRecords + 1 into ProcessedRecords
- DFMaskMessage "Records Processed:" && ProcessedRecords & return & ¬
- "Hold down ∩ú┐-option-mouse to interrupt."
- end repeat
- CleanUpStuff
- end FixedToVar
-
- on LoadAllData infile
- --loads all data into a single global variable for faster processing
- answer "Hypercard has approximately" && the heapspace div 1024 & "K"¬
- && "of free in which to process your data. If this figure isn’t larger"¬
- && "than your input file, please choose “Abort” and either allocate"¬
- && "more memory to HyperCard or run The Delimiter Fixer in Low Memory Mode."¬
- with "Continue" or "Abort"
- if it is "abort" then
- global DFImportFile
- close file DFImportFile
- return empty
- end if
- global DFDATA
- read from file infile until end --eof
- if the result contains "not enough memory" then
- answer "Sorry, there is not enough memory to load your data file."¬
- && "Either attempt this operation in Low Memory Mode or"¬
- && "split your data file into smaller segments." with "OK"
- return empty
- end if
- put it into DFDATA
- close file infile
- end LoadAllData
-
- on CleanUpStuff
- --cleans up after conversion procedures
- global DFDATA, DFImportFile, DFExportFile
- if the hilite of bg btn "Low Memory Mode" then close file DFImportFile
- close file DFExportFile
- put empty into DFDATA
- DFRemoveMask
- allowinterruption
- end CleanUpStuff
-
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- MASK ROUTINES
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
-
- on DFSetUpMask
- --sets up the mask field for user messages etc. during conversion run
- lock screen
- show bg fld mask
- put empty into bg fld mask
- repeat 6 times -- the number of visible lines
- put return after bg fld mask
- end repeat
- unlock screen with dissolve very fast
- end DFSetUpMask
-
- on DFRemoveMask
- --removes mask and clears out its field
- lock screen
- put empty into bg fld mask
- hide bg fld mask
- hide bg btn "OK"
- hide bg btn "Save..."
- unlock screen with dissolve very fast
- end DFRemoveMask
-
- on DFMaskMessage TheMess
- --puts THEMESS as a message to user during conversion at bottom of mask field
- put theMess into line (5 - the number of lines in themess) to 5 of bg fld mask
- -- 5 is the last visible line
- end DFMaskMessage
-
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- MENU ROUTINES
- ∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
- on DFSetUpMenu which
- show menubar
- if which is "on" then
- if there is not a menu "DF" then
- create menu "DF"
- put "Main Card,DF Help,DF Headers" into menu "DF"
- set the menuMessage of menuitem "Main Card" of menu "DF" to DFMainCard
- set the menuMessage of menuitem "DF Help" of menu "DF" to DFHelp
- set the menuMessage of menuitem "DF Headers" of menu "DF" to DFHeaders
- end if
- else if which is "off" then
- reset menubar
- end if
- end DFSetUpMenu
-
- on DFMainCard
- lock screen
- go to card "Main Card"
- unlock screen with dissolve
- end DFMainCard
-
- on DFHelp
- lock screen
- go to card "DF Help"
- unlock screen with wipe right fast
- end DFHelp
-
- on DFHeaders
- lock screen
- go to card "DF Headers"
- unlock screen with wipe right fast
- end DFheaders
-
- ∞∞∞∞∞∞∞∞FUNCTIONS∞∞∞∞∞∞∞∞∞∞∞∞∞
- function SomeOtherDelimiter
- ask "Please enter the delimiter of your choice:"
- if (it is empty) or (it is "Cancel") then return empty
- return it
- end SomeOtherDelimiter
-
- Function printField
- -- accumulates the text of the documentation together into one (big!) string for printing
- -- purposes.
- put "Intro" & return & "About" & return & "Operation" & return &¬
- "Info #1" & return & "Info #2" into TheFields
- repeat with i = 1 to the number of lines in TheFields
- put bg fld line i of TheFields & return & return & return after manual
- end repeat
- return manual
- end printField
-
- function FileFromPath path
- --requires hyperCard 2.1 or higher due to the use of THE ITEMDELIMITER.
- --returns the last item of a pathname, most probably a file
- set the itemdelimiter to colon
- return the last item of path
- end FileFromPath
-
- function IsValidHeader TheText
- --tests to see if the text supplied meets minimal criteria as a valid header...
- put stripReturnsAndSpaces(theText) into TheText
- put the number of chars in TheText into LastChar
- if (char 1 to 2 of TheText is "<<") then
- if char lastChar-1 to lastChar of TheText is ">>" then return true
- end if
- return false
- end IsValidHeader
-
- function theNextRecord
- global RecordDelimiter
- --loads the next "record" to be processed, whether from disk or memory. It
- --deletes each "record" from the global variable as it it processed.
- if the hilite of bg btn "Low Memory Mode" then
- global DFImportFile
- read from file DFImportFile until RecordDelimiter -- one "line"
- delete the last char of it --removes the record delimiter
- return it
- else
- global DFDATA, RecordDelimiter
- put the itemdelimiter into savedDelimiter
- set the itemdelimiter to RecordDelimiter
- get the first item of DFDATA
- delete the first item of DFDATA
- set the itemdelimiter to savedDelimiter
- return it
- end if
- end theNextRecord
-
- function UserInterrupt
- --optional interrupt
- if the commandkey is down then
- if (the optionkey is down) and (the mouse is down) then
- beep 3
- return true
- end if
- end if
- return false
- end UserInterrupt
-
- function stripReturnsAndSpaces theText
- --this is stolen from some Claris stack (I don't remember which) and is somewhat
- --modified to strip spaces from the front of a string and both spaces and returns from the
- --end. I think the original just removed things from the end
- repeat
- if (the last char of theText is space) or (the last char of theText is return)¬
- then delete the last char of theText
- else
- if (the first char of theText is space) then delete the first char of theText
- else return theText
- end if
- end repeat
- end stripReturnsAndSpaces
-
- function HitTest where, what
- --stolen from Jon Pugh's HPopUpMenu stack for the little arrow icons
- --on the ends of popup menus
- if what = "" or what = "btn" then
- repeat with i = the number of cd btns down to 1
- if where is within rect of cd btn i then
- if visible of cd btn i and name of cd btn i Γëá name of target
- then return "cd btn id " & the id of cd btn i
- end if
- end repeat
- repeat with i = the number of bg btns down to 1
- if where is within rect of bg btn i then
- if visible of bg btn i and name of bg btn i Γëá name of target
- then return " bg btn id "& the id of bg btn i
- end if
- end repeat
- end if
- if what = "" or what = "fld" then
- repeat with i = the number of cd flds down to 1
- if where is within rect of cd fld i then
- if visible of cd fld i and name of cd fld i Γëá name of target
- then return "cd fld id " & the id of cd fld i
- end if
- end repeat
- repeat with i = the number of bg flds down to 1
- if where is within rect of bg fld i then
- if visible of bg fld i and name of bg fld i Γëá name of target
- then return " bg fld id "& the id of bg fld i
- end if
- end repeat
- end if
- return ""
- end HitTest</script>
- <background id="2681" file="background_2681.xml" name="" />
- <background id="4711" file="background_4711.xml" name="" />
- <card id="2959" file="card_2959.xml" marked="false" name="Main Card" owner="2681" />
- <card id="4900" file="card_4900.xml" marked="false" name="DF Help" owner="4711" />
- <card id="4565" file="card_4565.xml" marked="false" name="DF Headers" owner="4711" />
- </stack>
-